﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Audio;

namespace Pacman
{
    
    class Pacman : TextureAnime
    {
        private Jeu jeu;

        private static Vector2 PACMAN_INITIAL_POS  = new Vector2(13 * 20, 17 * 20);
        private static Vector2 PACMAN_INITIAL_VIT = new Vector2(20, 0);
        
        protected int[] tDividVitesse = { 10, 20 };
        protected int indDividVitesse;

        //Variable permettant d'enregister un appuis sur une touche
        private Vector2 tryNewVitesse;

        //Gestion de l'image
        private const String BASE_PIC = "images/pacman_";
        private const String BASE_PIC_DIE = "images/Mort";
        private int pic;
        private int nextPic;
        private bool statePic;
        
        //Gestion des sons
        private bool isSonBeanOne;
        private SoundEffect[] soundBean;
        private SoundEffect soundDie;
        

        public Pacman(Jeu jeu) : base(jeu.getTexture2D(BASE_PIC + "1"), PACMAN_INITIAL_POS, PACMAN_INITIAL_VIT)
        {
            this.jeu = jeu;
            statePic = true;
            initialize();

            soundBean = new SoundEffect[3];
            soundBean[0] = jeu.getSoundEffect("sons/PelletEat1");
            soundBean[1] = jeu.getSoundEffect("sons/PelletEat2");
            soundBean[2] = jeu.getSoundEffect("sons/Invincible");
            soundDie = jeu.getSoundEffect("sons/PacmanEaten");
            indDividVitesse = 0;
        }

        /// <summary>
        /// Reinitialise le pacman
        /// </summary>
        public void initialize()
        {
            this.Position = PACMAN_INITIAL_POS;
            this.Vitesse = PACMAN_INITIAL_VIT;
            pic = nextPic = 1;
            isSonBeanOne = true;
            changePic();
        }//initialize()

        
        /// <summary>
        /// Fonction central d'affichage du pacman
        /// </summary>
        public int Animer()
        {
            //On vérifie d'abord si le fantome est sur le pacman. Cela est une éventualité car le pacman bouge avant les fantomes.
            for (int i = 0; i < 4; i++)
                if (PixToMap(this.Position) == PixToMap(jeu.TabFantome[i].Position))
                    return i;

            getKeyboard();

            //Si on est en train d'avancer entre deux cases
            if (this.Position.X % 20 != 0 || this.Position.Y % 20 != 0) {
                this.Position = this.Position + this.Vitesse / tDividVitesse[indDividVitesse];
                return 0;
            }
            
            //Si l'on est en fin de tunnel
            if (this.Position.X == (26 * 20) && this.Position.Y == (14 * 20))
            {
                this.Position = new Vector2(1 * 20, 14 * 20);
                jeu.Score++;
                jeu.Map[14, 1] = 2;
                jeu.BeanCpt--;
            }
            else if (this.Position.X == (1 * 20) && this.Position.Y == (14 * 20))
            {
                this.Position = new Vector2(26 * 20, 14 * 20);
                jeu.Score++;
                jeu.Map[14, 26] = 2;
                jeu.BeanCpt--;
            }
            
            //Si un nouveau déplacement a été demandé, on le test
            if (tryNewVitesse != null && (tryNewVitesse.X != 0 || tryNewVitesse.Y != 0) && Avance(tryNewVitesse))
            {   
                this.Vitesse = tryNewVitesse;
                tryNewVitesse = new Vector2(0,0);
                pic = nextPic;
            } else if (!Avance(this.Vitesse)) {
                return 0;
            }

            changePic();

            // Deuxieme verification
            for (int i = 0; i < 4; i++)
                if (PixToMap(this.Position) == PixToMap(jeu.TabFantome[i].Position))
                    return i;
            return 0;
        }
        //Animer()


        /// <summary>
        /// Fait avancer le pacman (lors du passage à une nouvelle case)
        /// </summary>
        /// <param name="vitesse"></param>
        /// <returns></returns>
        private bool Avance(Vector2 vitesse)
        {
            int x, y;
            Vector2 nextPosition = this.Position + vitesse;
            x = (int)nextPosition.X / 20; y = (int)nextPosition.Y / 20;
            if (jeu.Map[y, x] != 0 && jeu.Map[y, x] != 4)
            {
                if (jeu.Map[y, x] == 1 || jeu.Map[y, x] == 3)
                {
                    if (jeu.Map[y, x] == 3)
                    {
                        soundBean[2].Play();
                        jeu.goOnFantomePeur();
                    }
                    else
                    {
                        soundBean[(isSonBeanOne ? 0 : 1)].Play();
                        isSonBeanOne = !isSonBeanOne;
                    }
                    jeu.Score++;
                    jeu.Map[y, x] = 2;
                    jeu.BeanCpt--;
                }
                this.Position = this.Position + vitesse / tDividVitesse[indDividVitesse];
                return true;
            } else 
            return false;
        }//Avance()


        /// <summary>
        /// Gestion du clavier
        /// </summary>
        private void getKeyboard()
        {
            KeyboardState keyboard = Keyboard.GetState();
            if (keyboard.IsKeyDown(Keys.Down))
            {
                nextPic = 3;
                tryNewVitesse = new Vector2(0, 20);
            }
            else if (keyboard.IsKeyDown(Keys.Up))
            {
                nextPic = 4;
                tryNewVitesse = new Vector2(0, -20);
            }
            else if (keyboard.IsKeyDown(Keys.Right))
            {
                nextPic = 1;
                tryNewVitesse = new Vector2(20, 0);
            }
            else if (keyboard.IsKeyDown(Keys.Left))
            {
                nextPic = 2;
                tryNewVitesse = new Vector2(-20, 0);
            }
        }//getKeyboard()


        /// <summary>
        /// Modifie l'image, en fonction de l'état
        /// </summary>
        public void changePic()
        {
            this.Texture = jeu.getTexture2D(BASE_PIC + pic.ToString() + (statePic ? "f" : ""));
            statePic = !statePic;
        }

        public TimeSpan goOnDie(int state = 0) 
        {
            if (state == 0)
                soundDie.Play();
            if (state < 4)
                this.Texture = jeu.getTexture2D(BASE_PIC_DIE + state);
            return soundDie.Duration;
        }

        public Vector2 PixToMap(Vector2 _v)
        {
            return new Vector2(_v.X / 20, _v.Y / 20);
        }
    }
}
